import arrow
from flask import session
from app.validators import BaseForm
from wtforms.validators import Length, DataRequired
from wtforms.fields import StringField, BooleanField, FieldList
from app.libs.captcha import Captcha
from app.libs.regexp import PHONE_RE
from app.errors import ParameterError
from app.db.models.active import Follow


class SmsCaptchaForm(BaseForm):
    imageCode = StringField(validators=[DataRequired(), Length(max=10)])
    contactsPhone = StringField(validators=[DataRequired()])

    def validate_imageCode(self, value):
        if not (answer := session.pop(Captcha.key, None)):
            raise ParameterError(msg='请输入正确的图片验证码.')
        captcha = Captcha(answer=answer)
        expire_time = session.pop(Captcha.expire_key, None)
        if not captcha.check(value.data, expire_time):
            raise ParameterError(msg='请输入正确的图片验证码')

    def validate_contactsPhone(self, value):
        if not PHONE_RE.match(value.data):
            raise ParameterError(msg='请输入正确的手机号码')

        # 一分钟只允许获取一次短信验证码
        if last_sms_time := session.get('lastSmsTime', None):
            if (arrow.utcnow() - arrow.get(last_sms_time)).seconds < 55:
                raise ParameterError(msg='获取短信验证码过于频繁')
            else:
                session.pop('smsCode', None)
                session.pop('contactsPhone', None)
                session.pop('lastSmsTime', None)


class FollowForm(BaseForm):
    smsCode = StringField()
    follow = StringField(validators=[DataRequired()])

    def validate_follow(self, value):
        follow = Follow(**value.data)
        follow.activeName = 'ScanV（云监测）2021年中钜惠'
        # follow.activeName = '0元活动'
        follow.fromURL = 'https://www.scanv.com/activity'
        follow.validate()
        if follow.contactsPhone != session.get('contactsPhone'):
            raise ParameterError(msg='请输入正确的短信验证码')
        self.follow_data = follow

    def validate_smsCode(self, value):
        if value.data != session.get('smsCode'):
            raise ParameterError(msg='请输入正确的短信验证码')

        # 短信验证码是否过期
        if last_sms_time := session.get('lastSmsTime', None):
            if (arrow.utcnow() - arrow.get(last_sms_time)).seconds > 300:
                session.pop('smsCode', None)
                session.pop('contactsPhone', None)
                session.pop('lastSmsTime', None)
                raise ParameterError(msg='短信验证码已过期')
